//
//  APRules.m
//
//  Created by Sheng Luo on 8/20/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "APRules.h"
#import "NSData+Base64.h"

#define RULE_PATH @"/var/mobile/Library/Preferences/gfwlist.txt"

@interface APRules (Private)

- (void)addRule:(NSString *)rule toArray:(NSMutableArray *)array;

@end


@implementation APRules

static APRules *_instance;

+ (APRules *)sharedInstance {
    if (_instance == NULL) {
        _instance = [[APRules alloc] init];
    }
    return _instance;
}

- (id)init {
    if ((self = [super init])) {
        rulesInclusive = [[NSMutableArray alloc] init];
        rulesExclusive = [[NSMutableArray alloc] init];
        [self reload];
    }
    return self;
}

- (void)reload {
    [rulesInclusive removeAllObjects];
    [rulesExclusive removeAllObjects];
    
    NSString *strEncoded = [NSString stringWithContentsOfFile:RULE_PATH encoding:NSASCIIStringEncoding error:nil];
    NSData *dataDecoded = [NSData dataFromBase64String:strEncoded];
    NSString *strDecoded = [[NSString alloc] initWithData:dataDecoded encoding:NSASCIIStringEncoding];
    NSArray *rules = [strDecoded componentsSeparatedByString:@"\n"];
    [strDecoded release];
        
    for (NSString *rule in rules) {
        if ([rule hasPrefix:@"!"] || [rule length] == 0) {
            // If it's an empty line or a comment, just skip it.
        } else if ([rule hasPrefix:@"@@"]) {
            // Remove the prefix and add it to the exlusive array.
            [self addRule:[rule substringFromIndex:2] toArray:rulesExclusive];
        } else {
            // Add it to the inclusive array.
            [self addRule:rule toArray:rulesInclusive];
        }

    }
}

- (void)addRule:(NSString *)rule toArray:(NSMutableArray *)array {
    BOOL isRE = NO;
    NSString *keyword = rule;
    
    if ([rule hasPrefix:@"||"]) {
        keyword = [rule substringFromIndex:2];
    } else if ([rule hasPrefix:@"|"]) {
        keyword = [rule substringFromIndex:1];
    } else if ([rule hasPrefix:@"/"] && [rule hasSuffix:@"/"]) {
        NSRange range;
        range.location = 1;
        range.length = [rule length] - 2;
        keyword = [rule substringWithRange:range];
        
        isRE = YES;
    }

    NSPredicate *predicate;
    
    if (isRE) {
        predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", keyword];
    } else {
        predicate = [NSPredicate predicateWithFormat:@"SELF LIKE %@", [NSString stringWithFormat:@"*%@*", keyword]];
    }
    
    [array addObject:predicate];
}

- (BOOL)containsURL:(NSString *)url {
    BOOL result = NO;
    for (NSPredicate *predicate in rulesInclusive) {
        if ([predicate evaluateWithObject:url]) {
            result = YES;
        }
    }
    
    if (result) {
        for (NSPredicate *predicate in rulesExclusive) {
            if ([predicate evaluateWithObject:url]) {
                result = NO;
            }
        }
    }
    
    return result;
}

- (void)dealloc {
    [rulesInclusive release];
    [rulesExclusive release];
    [super dealloc];
}

@end
